home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 18 / develop 18 code / Graphics Speed on PwrPC / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-08  |  10.4 KB  |  550 lines  |  [TEXT/MMCC]

  1.  
  2. #include "main.h"
  3. #include "BlitCmp.h"
  4.  
  5. Boolean        gQuit;
  6. Rect        gSrcRect, gDstRect;
  7. GWorldPtr    gSrcWorld = nil;
  8. WindowPtr    gTheWindow;
  9.  
  10. #ifdef powerc
  11.     QDGlobals qd;
  12. #endif
  13.  
  14.  
  15.  
  16. main()
  17. {
  18.     MaxApplZone();                    /* Expand the heap so code segments load
  19.                                        at the top */
  20.     InitToolbox();                    /* Initialize the program */
  21.     MainEventLoop();                /* Call the main event loop */
  22. }
  23.  
  24.  
  25. void
  26. InitToolbox()
  27. {
  28.     Handle        menuBar;
  29.     EventRecord event;
  30.     short        count;
  31.  
  32.     gQuit = FALSE;
  33.  
  34.     InitGraf((Ptr) &qd.thePort);
  35.     InitWindows();
  36.     InitMenus();
  37.     InitDialogs(nil);
  38.     InitCursor();
  39.  
  40.     menuBar = GetNewMBar(kMenuBarId);                    /* Read menus into menu bar */
  41.     if ( menuBar != nil )
  42.     {
  43.         SetMenuBar(menuBar);                            /* Install menus */
  44.         DisposHandle(menuBar);
  45.         
  46.         AddResMenu(GetMHandle(mApple), 'DRVR');            /* Add DA names to Apple menu */
  47.         DrawMenuBar();
  48.     }
  49.     else
  50.         DebugStr("\pCould not get menubar");
  51.     
  52.     DoNewWindow();
  53.     
  54.     if ((gSrcWorld = GetPictWorld(&gSrcRect, 0, 128)) == nil)
  55.     {
  56. //        DebugStr("\pCould not get the World");
  57.         return;
  58.     }
  59.  
  60.     gDstRect = gSrcRect;
  61.     
  62.     /* make sure the left of the dst rect is below 200 so we don't overwrite the times */
  63.     if ( gDstRect.left < 200 )
  64.         {
  65.         OffsetRect(& gDstRect, 200, 0 );
  66.         }
  67. }
  68.  
  69.  
  70. void
  71. MainEventLoop()
  72. {
  73.     RgnHandle    cursorRgn;
  74.     EventRecord    event;
  75.     Point        mouse;
  76.  
  77.     cursorRgn = nil;
  78.     while ( ! gQuit )
  79.     {
  80.         if ( WaitNextEvent(everyEvent, &event, MAXLONG, cursorRgn) )
  81.             DoEvent(&event);
  82.     }
  83. }
  84.  
  85.  
  86. void
  87. DoEvent(EventRecord *event)
  88. {
  89.     switch ( event->what )
  90.     {
  91.         case mouseDown:
  92.             DoMouseDown(event);
  93.             break;
  94.             
  95.         case keyDown:
  96.         case autoKey:
  97.             DoKeyPress(event);
  98.             break;
  99.             
  100.         case updateEvt:
  101.             DoUpdate(event);
  102.             break;
  103.     }
  104. }
  105.  
  106.  
  107. void
  108. DoKeyPress(EventRecord *event)
  109. {
  110.     char    key;
  111.  
  112.     key = event->message & charCodeMask;
  113.     if ( event->modifiers & cmdKey )        /* Command key down? */
  114.     {
  115.         DoMenuCommand(MenuKey(key));
  116.     }
  117. }
  118.  
  119.  
  120. void
  121. DoMouseDown(EventRecord *event)
  122. {
  123.     long        newSize;
  124.     Rect        growRect;
  125.     WindowPtr    theWindow;
  126.     short        part = FindWindow(event->where, &theWindow);
  127.  
  128.     switch ( part )
  129.     {
  130.         case inMenuBar:                /* Process a mouse menu command (if any) */
  131.             DoMenuCommand(MenuSelect(event->where));
  132.             break;
  133.             
  134.         case inSysWindow:            /* Let the system handle the mouseDown */
  135.             SystemClick(event, theWindow);
  136.             break;
  137.             
  138.         case inContent:
  139.             if ( theWindow != FrontWindow() )
  140.                 SelectWindow(theWindow);
  141.             else
  142.                 DoContentClick(event, theWindow);
  143.             break;
  144.             
  145.         case inDrag:                /* Pass screenBits.bounds to get all gDevices */
  146.             DragWindow(theWindow, event->where, &qd.screenBits.bounds);
  147.             break;
  148.             
  149.         case inGrow:
  150.             growRect = qd.screenBits.bounds;
  151.             growRect.top = growRect.left = 80;        /* Arbitrary minimum size. */
  152.             newSize = GrowWindow(theWindow, event->where, &growRect);
  153.             if (newSize != 0)
  154.             {
  155.                 InvalidateScrollbars(theWindow);
  156.                 SizeWindow(theWindow, LoWord(newSize), HiWord(newSize), TRUE);
  157.                 InvalidateScrollbars(theWindow);
  158.             }
  159.             break;
  160.             
  161.         case inGoAway:
  162.             if (TrackGoAway(theWindow, event->where))
  163.             {
  164.                 CloseAnyWindow(theWindow);
  165.                 gQuit = true;
  166.             }
  167.             break;
  168.     }
  169. }
  170.  
  171.  
  172. void
  173. DoUpdate(EventRecord *event)
  174. {
  175.     WindowPtr    theWindow = (WindowPtr) event->message;
  176.     
  177.     if ( IsAppWindow(theWindow) )
  178.     {
  179.         BeginUpdate(theWindow);    /* This sets up the visRgn */
  180.         if (! EmptyRgn(theWindow->visRgn))
  181.         {                        /* Draw if updating needs to be done */
  182.             SetPort(theWindow);
  183.             EraseRgn(theWindow->visRgn);
  184.             DoUpdateWindow(event);
  185.             DrawGrowIcon(theWindow);
  186.         }
  187.         EndUpdate(theWindow);
  188.     }
  189. }
  190.  
  191. void
  192. DoMenuCommand(long menuResult)
  193. {
  194.     short        menuID;                /* The resource ID of the selected menu */
  195.     short        menuItem;            /* The item number of the selected menu */
  196.     Str255        daName;
  197.     FSSpec        theFile;
  198.  
  199.     menuID = HiWord(menuResult);
  200.     menuItem = LoWord(menuResult);
  201.     switch ( menuID )
  202.     {
  203.         case mApple:
  204.             switch ( menuItem )
  205.             {
  206.                 case iAbout:
  207.                     (void) Alert(kAboutAlertId, nil);
  208.                     break;
  209.                 default:            /* All non-About items in this menu are DAs */
  210.                     GetItem(GetMHandle(mApple), menuItem, daName);
  211.                     (void) OpenDeskAcc(daName);
  212.                     break;
  213.             }
  214.             break;
  215.             
  216.         case mFile:
  217.             switch ( menuItem )
  218.             {
  219.                 case iQuit:
  220.                     gQuit = true;
  221.                     break;
  222.             }
  223.             break;
  224.             
  225.         case mEdit:
  226.             switch (menuItem)
  227.             {
  228.                 /* Call SystemEdit for DA editing & MultiFinder */
  229.                 /* since we don’t do any Editing */
  230.                 case iUndo:
  231.                 case iCut:
  232.                 case iCopy:
  233.                 case iPaste:
  234.                 case iClear:
  235.                     (void) SystemEdit(menuItem - 1);
  236.                     break;
  237.             }
  238.             break;
  239.     }
  240.     HiliteMenu(0);        /* Unhighlight what MenuSelect or MenuKey hilited */
  241. }
  242.  
  243. void
  244. CloseAnyWindow(WindowPtr window)
  245. {
  246.     if (IsDAWindow(window))
  247.     {
  248.         CloseDeskAcc( ( (WindowPeek) window )->windowKind );
  249.     } else if (IsDialogWindow(window))
  250.     {
  251.         HideWindow(window);
  252.     }
  253.     else if (IsAppWindow(window))
  254.     {
  255.         CloseWindow(window);
  256.     }
  257. }
  258.  
  259. Boolean
  260. IsAppWindow(WindowPtr window)
  261. {
  262.     short        windowKind;
  263.  
  264.     if ( window == nil )
  265.         return false;
  266.     else
  267.     {
  268.         windowKind = ((WindowPeek) window)->windowKind;
  269.         return ((windowKind >= userKind) || (windowKind == dialogKind));
  270.     }
  271. }
  272.  
  273. Boolean
  274. IsDAWindow(WindowPtr window)
  275. {
  276.     if ( window == nil )
  277.         return false;
  278.     else
  279.         return ( ((WindowPeek) window)->windowKind < 0 );
  280. }
  281.  
  282. Boolean
  283. IsDialogWindow(WindowPtr window)
  284. {
  285.     if ( window == nil )
  286.         return false;
  287.     else
  288.         return ( ((WindowPeek) window)->windowKind == dialogKind );
  289. }
  290.  
  291. void
  292. DoNewWindow(void)
  293. {
  294.     WindowPtr    newWindow;
  295.     Rect        bounds;
  296.  
  297.     SetRect(&bounds, 0, 40, 620, 480);
  298.     gTheWindow = NewCWindow(nil, &bounds, "\pBlitCmp", false, documentProc,
  299.                                         (WindowPtr)(-1), true, 0L);
  300.     
  301.     if (gTheWindow == nil)
  302.         return;
  303.  
  304.     ((WindowPeek)gTheWindow)->windowKind = userKind;
  305.     
  306.     ShowWindow(gTheWindow);
  307.     SetPort(gTheWindow);
  308. }
  309.  
  310.  
  311. void
  312. DoContentClick(EventRecord *event, WindowPtr win)
  313. {
  314.     Point pt;
  315.     
  316.     SetPort((GrafPtr)win);
  317.     pt = event->where;
  318.     LocalToGlobal(&pt);
  319.     
  320.     InvalRect(&win->portRect);
  321. }
  322.  
  323. void
  324. DoUpdateWindow(EventRecord *event)
  325. {
  326.     BlitProcPtr        theWinner;
  327.     PixMapHandle    srcPixHandle;
  328.     
  329.     if (gSrcWorld == nil)                    // Not yet ready to update
  330.         return;
  331.         
  332.     if ((srcPixHandle = GetGWorldPixMap(gSrcWorld)) == nil)
  333.     {
  334. //        DebugStr("\pCould not fetch the source PixMapHandle");
  335.         return;
  336.     }
  337.             
  338.     HLock((Handle) srcPixHandle);
  339.     LockPixels(srcPixHandle);    
  340.  
  341.     theWinner =    BestBlitter((BlitProcPtr)MyCopyPixels, srcPixHandle, &gSrcRect, &gDstRect);
  342.     
  343.     UnlockPixels(srcPixHandle);
  344.     HUnlock((Handle) srcPixHandle);    
  345.     
  346.     MoveTo(10, 100);
  347.     if (theWinner == (BlitProcPtr) MyCopyPixels)
  348.         DrawString("\pUse the other Blit Proc...");
  349.     else
  350.         DrawString("\pIt's better to use CopyBits()");
  351. }
  352.  
  353.  
  354. pascal void MyCopyPixels(BitMapPtr srcBits, BitMapPtr dstBits,
  355.                 Rect *srcRect, Rect *dstRect, 
  356.                 short mode, RgnHandle mask)
  357. {
  358. PixMapPtr        srcPM;
  359. PixMapPtr        dstPM;
  360. long            dstLeft;
  361. long            dstRight;
  362. long            srcLeft;
  363. long            srcRowBytes;
  364. long            dstRowBytes;
  365. long *            srcRow;
  366. long *            dstRow;
  367. long *            srcPtr;
  368. long *            dstPtr;
  369. long            leftMask;
  370. long            notLeftMask;
  371. long            rightMask;
  372. long            notRightMask;
  373. long            dstLong;
  374. short            width;
  375. short            dstLongs;
  376. short            height;
  377. long            offset;
  378.  
  379.     srcPM = (PixMapPtr) srcBits;
  380.     dstPM = (PixMapPtr) dstBits;
  381.     
  382.     srcRow = (long *) srcPM->baseAddr;
  383.     dstRow = (long *) dstPM->baseAddr;
  384.     
  385.     srcRowBytes = srcPM->rowBytes & 0x3fff;
  386.     dstRowBytes = dstPM->rowBytes & 0x3fff;
  387.     
  388.     // get the bit offset to the src left edge
  389.     srcLeft = srcRect->left - srcPM->bounds.left;
  390.     srcLeft *= srcPM->pixelSize;
  391.     
  392.     // offset the src ptr to the first long
  393.     srcRow += srcLeft >> 5;
  394.     
  395.     // get the bit offset to the dst left and right edges
  396.     dstLeft = dstRect->left - dstPM->bounds.left;
  397.     dstLeft *= dstPM->pixelSize;
  398.     dstRight = dstRect->right - dstPM->bounds.left;
  399.     dstRight *= dstPM->pixelSize;
  400.     
  401.     // get the number of middle longs to do minus the left edge long
  402.     dstLongs = dstRight - dstLeft;
  403.     dstLongs >>= 5;
  404.     dstLongs -= 2;
  405.     
  406.     // offset the dst Ptr to the first long
  407.     dstRow += dstLeft >> 5;
  408.     
  409.     // now compute left and right masks for the dst
  410.     dstLeft &= 0x1f;
  411.     leftMask = ( 1 << dstLeft ) - 1;
  412.     notLeftMask = ~leftMask;
  413.     
  414.     dstRight &= 0x1f;
  415.     notRightMask = ( 1 << dstRight ) - 1;
  416.     rightMask = ~notRightMask;
  417.     
  418.     // offset the src and dst ptrs to the first row
  419.     offset = srcRect->top - srcPM->bounds.top;
  420.     offset *= srcRowBytes;
  421.     srcRow += (long *) offset;
  422.     
  423.     offset = dstRect->top - dstPM->bounds.top;
  424.     offset *= dstRowBytes;
  425.     dstRow += (long *) offset;
  426.     
  427.     height = dstRect->bottom - dstRect->top - 1;
  428.         
  429.     /* check if we need to do the left and right mask */
  430.     if ( leftMask )
  431.         {
  432.         if ( notLeftMask == 0 )
  433.             {
  434.             leftMask = 0;
  435.             dstLongs++;
  436.             }
  437.         }
  438.         
  439.     if ( rightMask )
  440.         {
  441.         if ( notRightMask == 0 )
  442.             {
  443.             rightMask = 0;
  444.             dstLongs++;
  445.             }
  446.         }
  447.         
  448.     for ( ; height >= 0; --height )
  449.         {
  450.         srcPtr = srcRow;
  451.         dstPtr = dstRow;
  452.         
  453.         /* do the masked left edge */
  454.         if ( leftMask )
  455.             {
  456.             dstLong = *srcPtr++ & leftMask;
  457.             dstLong |= *dstPtr & notLeftMask;
  458.             *dstPtr++ = dstLong;
  459.             }
  460.         
  461.         /* do the middle longs */
  462.         for ( width = dstLongs; width >= 0; --width )
  463.             {
  464.             *dstPtr++ = *srcPtr++;
  465.             }
  466.         
  467.         /* do the masked right edge */
  468.         if ( rightMask )
  469.             {
  470.             dstLong = *srcPtr & rightMask;
  471.             dstLong |= *dstPtr & notRightMask;
  472.             *dstPtr = dstLong;
  473.             }
  474.         
  475.         /* bump to the next row */
  476.         srcRow += (long *) srcRowBytes;
  477.         dstRow += (long *) dstRowBytes;
  478.         }
  479. }
  480.  
  481. GWorldPtr GetPictWorld(Rect *srcRect, short depth, short pictID)
  482. {
  483.     GWorldPtr    srcWorld, oldWorld;
  484.     GDHandle    oldGD;
  485.     PicHandle    thePict;
  486.     Rect        saveSrcRect;
  487.  
  488.     if ((thePict = GetPicture(pictID)) == nil)
  489.     {
  490.         DebugStr("\pError getting the pict");
  491.         return nil;
  492.     }
  493.     
  494.     *srcRect = (**thePict).picFrame;    // Make our GWorld the size of the pict
  495.  
  496. #if 1
  497.     SetRect( srcRect, 200, 0, 600, 400 );
  498. #endif
  499.     
  500.     // if depth zero, convert our rectangle to global coords to get screen depth and alignment
  501.     if ( depth == 0 )
  502.         {
  503.         saveSrcRect = *srcRect;
  504.         LocalToGlobal( (Point *) srcRect );
  505.         LocalToGlobal( &((Point *) srcRect)[1] );
  506.         }
  507.         
  508.     GetGWorld(&oldWorld, &oldGD);
  509.     if (NewGWorld(&srcWorld, depth, srcRect, nil, nil, useTempMem) == noErr && srcWorld != nil)
  510.     {    
  511.         /* make sure the src rect is set to the offscreen's rect */
  512.         *srcRect = srcWorld->portRect;
  513.         
  514.         SetGWorld(srcWorld, nil);        // Drawing goes to our new GWorld
  515.         EraseRect(srcRect);                // Clear it out
  516.     
  517.         DrawPicture(thePict, srcRect);    // Draw our picture
  518.     }
  519.     else
  520.     {
  521.         SysBeep( 5 );
  522. //        DebugStr("\pNewGWorld() failed!");
  523.         srcWorld = nil;
  524.     }
  525.     
  526.     SetGWorld(oldWorld, oldGD);
  527.  
  528.     ReleaseResource((Handle) thePict);
  529.     return srcWorld;
  530. }
  531.  
  532.  
  533. void
  534. InvalidateScrollbars(WindowPtr theWindow)
  535. {
  536.     Rect    tempRect;
  537.  
  538.     SetPort(theWindow);
  539.  
  540.     tempRect = theWindow->portRect;
  541.     tempRect.left = tempRect.right - 15;
  542.     InvalRect(&tempRect);
  543.     EraseRect(&tempRect);
  544.  
  545.     tempRect = theWindow->portRect;
  546.     tempRect.top = tempRect.bottom - 15;
  547.     InvalRect(&tempRect);
  548.     EraseRect(&tempRect);
  549. }
  550.